/*
-- IOTA Crypto Core
--
-- 2018 by Thomas Pototschnig <microengineer18@gmail.com>
-- discord: pmaxuw#8292
-- https://gitlab.com/iccfpga-rv
--
-- Permission is hereby granted, free of charge, to any person obtaining
-- a copy of this software and associated documentation files (the
-- "Software"), to deal in the Software without restriction, including
-- without limitation the rights to use, copy, modify, merge, publish,
-- distribute, sublicense, and/or sell copies of the Software, and to
-- permit persons to whom the Software is furnished to do so, subject to
-- the following conditions:
--
-- The above copyright notice and this permission notice shall be
-- included in all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWAR
*/
#pragma once

#include <type_traits>
#include <ArduinoJson.h>
#include "secure/sbi.h"

namespace API {
	enum {
		API_SUCCESS = 200,
		API_ERROR = 400
	};

	enum AuthMethod {
		AUTH = 0, HUMAN = 1
	};

	struct apiFlagsStruct {
		bool 		debugRS232Output;
		bool 		debugSemihostingOutput;
		AuthMethod	authMethod;

	};

	typedef int (*apiCallType)();

	struct apiCallsStruct {
		const char* command;
		apiCallType fPtr;
	};

	extern JsonObject json;

	template<typename T>
	bool optional(JsonObject& json, const char* key) {
		if (!json.containsKey(key)) {
			return true;
		}
		if (!json[key].is<T>())
			return false;

		if (std::is_same<T, JsonObject>::value) {
			JsonObject tmp = json[key];
			if (tmp.isNull())
				return false;
		}

		if (std::is_same<T, JsonArray>::value) {
			JsonArray tmp = json[key];
			if (tmp.isNull())
				return false;
		}
		return true;
	}

	template<typename T>
	bool exists(JsonObject& json, const char* key) {
		if (!json.containsKey(key))
			return false;
		return optional<T>(json, key);
	}

	bool attachToTangle(Transaction* tx, const char* trunkTransaction, const char* branchTransaction, int minWeightMagnitude, int64_t timestamp, char* lastTXHash);

	int apiError(const char* error, bool output  = false);
	int apiError(SBIError error);

	bool registerAPICall(const char* command, apiCallType fPtr);
	void runAPI();

	bool registerAPIBase();

};

